package com.example.droideep.fragment.animstudy;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.example.droideep.R;
import com.example.droideep.common.activities.SimpleFragmentBase;

import butterknife.InjectView;
import butterknife.OnClick;
import droideep.library.widget.FloatingActionButton;


public class AnimationStudyFragment extends SimpleFragmentBase {

    private static final String TAG = AnimationStudyFragment.class.getSimpleName();

    @InjectView(R.id.floating_action_button)
    FloatingActionButton mFab;

    OnParabolicMotionListener motionListener;

    OnAnimatorSetListener animatorSetListener;

    OnLayoutAnimationsListener layoutAnimationsListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            setOnParabolicMotionListener((OnParabolicMotionListener) activity);
            setOnAnimatorSetListener((OnAnimatorSetListener) activity);
            setOnLayoutAnimationsListener((OnLayoutAnimationsListener) activity);
        } catch (Exception e) {
            throw new ClassCastException("Activity must implement OnParabolicMotionListener");
        }
    }

    @Override
    protected int getContentResId() {
        return R.layout.fragment_animation_study;
    }

    @OnClick(R.id.valueAnimator)
    public void valueAnimator(View view) {
        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
        anim.setDuration(300);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float currentValue = (float) animation.getAnimatedValue();
                Log.d(TAG, "current value is " + currentValue);
            }
        });
        anim.start();
    }

    @OnClick(R.id.alpha)
    public void alpha(View view) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);
        animator.setDuration(5000);
        animator.start();
    }

    @OnClick(R.id.rotation)
    public void rotation(View view) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", view.getRotation(), 320f);
        animator.setDuration(5000);
        animator.start();
    }

    @OnClick(R.id.translate)
    public void tranlation(View view) {
        final float currTranslationX = view.getTranslationX();
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", view.getTranslationX(), 5000f, currTranslationX);
        animator.setDuration(2000);
        animator.start();
    }

    @OnClick(R.id.animatorSet)
    public void animatorSet(View view) {
        ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationY", -500f, 0f);
        ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
        ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(rotate).with(fadeOut).after(moveIn);
        animatorSet.setDuration(5000L);
        animatorSet.start();
    }

    @OnClick(R.id.rotateAnimRun)
    public void rotateAnimRun(final View view) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "zl", 1.0f, 0.0f, 1.0f);
        animator.setDuration(1000L).start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                view.setAlpha(value);
                view.setScaleX(value);
                view.setScaleY(value);
            }
        });
    }

    @OnClick(R.id.propertyValuesHolder)
    public void propertyValuesHolder(View view) {
        PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f, 1.0f);
        PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f, 1.0f);
        PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f, 1.0f);
        ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000L).start();
    }

    @OnClick(R.id.verticalRun)
    public void verticalRun(View view) {
        final int parentHeight = ((FrameLayout) mFab.getParent()).getHeight();
        ValueAnimator animator = ValueAnimator.ofFloat(0, parentHeight - mFab.getHeight());
        animator.setTarget(mFab);
        animator.setDuration(2000L);
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                final float transY = (float) animation.getAnimatedValue();
                mFab.setTranslationY(transY);
            }
        });
    }

    @OnClick(R.id.parabolic_motion)
    public void parabolicMmotion() {
        if (motionListener != null) {
            motionListener.onParabolicMotion();
        }
    }

    @OnClick(R.id.fade_out)
    public void fadeOut() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(mFab, "alpha", 1.0f, 0.0f);
        animator.setDuration(1000L);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                ViewGroup parent = (ViewGroup) mFab.getParent();
                if (parent != null) {
                    parent.removeView(mFab);
                }
            }
        });
        animator.start();
    }

    @OnClick(R.id.animator_set)
    public void animatorSet() {
        if (animatorSetListener != null) {
            animatorSetListener.onAnimatorSet();
        }
    }

    @OnClick(R.id.use_xml)
    public void useXml() {
        Animator animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.scalex);
        animator.setTarget(mFab);
        animator.start();
    }

    @OnClick(R.id.layout_animations)
    public void layoutAnimations() {
        if (layoutAnimationsListener != null) {
            layoutAnimationsListener.onLayoutAnimations();
        }
    }

    @OnClick(R.id.view_animate)
    public void viewAnimate() {
        final int parentHeight = ((FrameLayout) mFab.getParent()).getHeight();
        mFab.animate()
                .alpha(0)
                .y(parentHeight / 2).setDuration(1000)
                .withStartAction(new Runnable() {
                    @Override
                    public void run() {
                        Log.e(TAG, "Start");
                    }
                }).withEndAction(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, "End");
            }
        }).start();
    }

    public void setOnParabolicMotionListener(OnParabolicMotionListener listener) {
        motionListener = listener;
    }

    public interface OnParabolicMotionListener {
        void onParabolicMotion();
    }

    public void setOnAnimatorSetListener(OnAnimatorSetListener listener) {
        animatorSetListener = listener;
    }

    public interface OnAnimatorSetListener {
        void onAnimatorSet();
    }

    public void setOnLayoutAnimationsListener(OnLayoutAnimationsListener listener) {
        layoutAnimationsListener = listener;
    }

    public interface OnLayoutAnimationsListener {
        void onLayoutAnimations();
    }

}
